package com.itheima.d11_serializable.service;

import com.itheima.d11_serializable.entity.Account;
import com.itheima.d11_serializable.utils.ObjectUtil;

import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;



/**
 * 业务类：提供ATM取款机系统的所有业务功能
 *       1.展示欢迎欢迎菜单
 *       2.登录功能
 *       3.开户功能
 *       4.展示主功能菜单
 *       5.查看账户信息
 *       6.存款功能
 *       7.取款功能
 *       8.转账功能
 *       9.修改密码
 *       10.退出系统==转账==
 * 请输入转入的账户：
 * 911
 * 您当前要为*四女生转账！
 * 请输入姓氏确认：
 * 李
 * 请输入转账金额：
 * 1000
 * 恭喜，张三先生转帐成功！余额：0.0
 *       11.注销功能
 */
public class ATMService {

    private Scanner sc = new Scanner(System.in); // 创建一个扫描器，整个类中都使用

    private ArrayList<Account> accounts = new ArrayList<>(); // 创建一个集合，用于管理ATM系统所有账户信息

    private Account loginAccount; // 登录成功后的账户对象


    public ATMService() throws Exception {
        try {
            accounts = ObjectUtil.loadAccount(); // 加载账户信息
        } catch (Exception e) {
            //反序列化对象输入流，第一读取空文件，会触发异常
            System.out.println("第一次，加载账户文件... ...");
            accounts = new ArrayList<>();
        }

    }



    // 展示欢迎欢迎菜单
    public void welcomeView() throws IOException {
        //添加测试账户
        //accounts.add(new Account("110","张三","123","男",1000.0,200.0));
        //accounts.add(new Account("911","李四","321","女",500.0,100.0));


        //程序提供ATM服务
        while (true) {
            System.out.println("==欢迎进入黑马银行ATM系统==");
            System.out.println("1.用户登录");
            System.out.println("2.用户开户");
            System.out.println("请选择您要操作的命令：");
            int choose = sc.nextInt();
            switch (choose){
                case 1:
                    System.out.println("用户登录");
                    login();
                    break;
                case 2:
                    System.out.println("用户开户");
                    register();
                    break;
                default:
                    System.out.println("输入的选项有误！");
            }
            System.out.println();
            System.out.println();
        }
    }

    // 登录功能
    public void login() throws IOException {
        //1.校验系统是否没有账户
        if(accounts.size() == 0){
            System.out.println("系统暂无账户，请先开户在进行登录！");
            return;
        }

        //2.接收用户登录信息，校验用户登录信息
        String cardId = null;
        while (true) {
            //2.1 接收并校验用户输入的卡号
            System.out.println("请您输入登录卡号：");
            cardId = sc.next();

            //2.2 校验用户输入的卡号
            loginAccount = findByCardId(cardId);
            if(loginAccount != null){
                break;
            }
            System.out.println("输入的卡号有误，请重新输入！");
        }

        //2.2 接收并校验用户输入的密码
        while (true) {
            System.out.println("请您输入登录密码：");
            String password = sc.next();
            if(password.equals(loginAccount.getPassword())){
                break;
            }
            System.out.println("输入的密码有误，请重新输入！");
        }

        //3.展示登录结果
        System.out.println("恭喜您，"+loginAccount.getUsername()+"，您已进入系统，您的卡号是："+loginAccount.getCardId());

        //4.展示主功能菜单
        //登录成功后，展示主功能菜单
        showMainView();
    }

    // 开户功能
    public void register() throws IOException {
        //1.接收用户录入的账户信息
        System.out.println("请输入账户用户名：");
        String username = sc.next();

        //持续的录入合法性别
        String sex = null;
        while (true) {
            System.out.println("请输入您的性别：");
            sex = sc.next();

            if("男".equals(sex) || "女".equals(sex)){
                break;
            }
            System.out.println("输入的性别有误，请重新输入！");
        }

        //持续验证密码的一致性
        String password = null;
        while (true) {
            System.out.println("请输入账户密码：");
            password = sc.next();

            System.out.println("请输入确认密码");
            String passswordOK = sc.next();

            if(password.equals(passswordOK)){
                break;
            }
            System.out.println("输入的密码不一致，请重新输入！");
        }

        System.out.println("请输入每次取现的额度：");
        double limit = sc.nextDouble();

        //持续生成一个可用卡号
        String cardId = null;
        while (true) {
            //系统生成卡号：随机8位数字，不重复
            cardId = createCardId();
            if(findByCardId(cardId)==null){
                break;
            }
            System.out.println("该卡号已存在！请重新输入！");
        }


        //2.创建账户实体类，封装用户开户信息到账户实体对象
        Account acc = new Account(cardId,username,password,sex,0.0,limit);

        //3.添加账户对象添加到业务类账户集合中
        accounts.add(acc);

        //4.提示开户结果
        System.out.println("恭喜，"+acc.getUsername()+"，您开户成功，您的卡号是："+acc.getCardId());

        //开户成功：序列化操作
        ObjectUtil.saveObject(accounts);
    }


    //根据卡号，查找账户
    private Account findByCardId(String cardId){
        for (Account account : accounts) {
            if(account.getCardId().equals(cardId)){
                //查找到卡号对应的账户
                return account;
            }
        }
        //没有查找到此账户
        return null;
    }

    // 生成卡号
    public String createCardId(){
        String cardId = "";
        Random random = new Random();
        for (int i = 0; i < 8; i++) {
            cardId += random.nextInt(10); // 0~9
        }
        return cardId;
    }


    // 展示主功能菜单
    public void showMainView() throws IOException {
        //持续的展示和提供菜单服务
        while (true) {
            System.out.println("==黑马"+loginAccount.getUsername()+"您可以办理以下业务==");
            System.out.println("1.查询账户");
            System.out.println("2.存款");
            System.out.println("3.取款");
            System.out.println("4.转账");
            System.out.println("5.修改密码");
            System.out.println("6.退出");
            System.out.println("7.注销账户");
            System.out.println("请选择：");
            int choose = sc.nextInt();
            switch (choose) {
                case 1:
                    System.out.println("==查询账户==");
                    showAccountInfo();
                    break;
                case 2:
                    System.out.println("==存款==");
                    saveMoney();
                    break;
                case 3:
                    System.out.println("==取款==");
                    takeoutMoney();
                    break;
                case 4:
                    System.out.println("==转账==");
                    transferMoney();
                    break;
                case 5:
                    System.out.println("==修改密码==");
                    break;
                case 6:
                    System.out.println("==退出系统==");
                    System.out.println("黑马"+loginAccount.getUsername()+"，退出系统成功！欢迎下次使用！");

                    //退出系统：序列化操作
                    ObjectUtil.saveObject(accounts);

                    return;
                case 7:
                    System.out.println("==注销账户==");
                    if(destroyAccount()){
                        System.out.println("注销成功！欢迎下次使用！");
                        return;
                    }else{
                        break;
                    }
                default:
                    System.out.println("输入的选项有误！");
            }
            System.out.println();
            System.out.println();
        }

    }



    // 查看账户信息
    public void showAccountInfo(){
        System.out.println("账户卡号："+loginAccount.getCardId());
        System.out.println("账户姓名："+loginAccount.getUsername());
        System.out.println("账户性别："+loginAccount.getSex());
        System.out.println("账户余额："+loginAccount.getMoney());
        System.out.println("每次取现额度："+loginAccount.getLimit());
    }

    // 存款功能
    public void saveMoney(){
        //1.提示输入存款金额
        double money = 0;
        while (true) {
            System.out.println("请输入存款金额：");
            money = sc.nextDouble();

            if(money > 0){
                break;
            }
            System.out.println("输入的存款金额有误！请重新输入！");
        }

        //2.实现存款，更新当前账户的余额
        loginAccount.setMoney(     money   +   loginAccount.getMoney()     );

        //3.提示存款结果
        System.out.println("恭喜，"+loginAccount.getUsername()+"存款成功！余额："+loginAccount.getMoney());
    }

    // 取款功能
    public void takeoutMoney(){

        //1.判断当前账户余额是否大于等于100，如果不满足，则无法进行取款操作
        if(loginAccount.getMoney() < 100){
            System.out.println("穷鬼，没钱取个锤子啊！！！");
            return;
        }

        //2.持续提示输入正确的取款金额
        double money = -1;
        while (true) {
            System.out.println("请输入取款金额：");
            money = sc.nextDouble();

            //3.判断账户余额是否充足
            if(money   >   loginAccount.getMoney()){
                System.out.println("当前账户余额："+loginAccount.getMoney()+"，余额不足！取款"+money+"失败！");
                continue;
            }

            //4.判断取款金额是否大于每次取现额度
            if(money  >   loginAccount.getLimit()){
                System.out.println("每次取现额度为："+loginAccount.getLimit()+"，取款金额超出了限制！取款失败！");
                continue;
            }
            break;
        }

        //5.取款操作：更新账户余额
        loginAccount.setMoney(        loginAccount.getMoney()     -     money          );

        //6.提示结果
        System.out.println("恭喜，"+loginAccount.getUsername()+"取款成功！余额："+loginAccount.getMoney());
    }

    // 转账功能
    public void transferMoney(){
        //1.判断系统是否存在其他账户
        if( accounts.size() < 2 ){
            System.out.println("系统暂无其他账户，无法进行转账操作！");
            return;
        }

        //2.判断账户是否有钱
        if(loginAccount.getMoney() == 0){
            System.out.println("穷鬼，没钱转个锤子啊！！！");
            return;
        }

        //3.输入转入的账户
        //持续接收一个存在的卡号
        Account toAccount = null; //调用提取的根据卡号查询账户的方法
        while (true) {
            System.out.println("请输入转入的账户：");
            String cardId = sc.next();
            toAccount = findByCardId(cardId);

            if(toAccount == null){
                System.out.println("没有找到该账户！");
                continue;
            }
            break;
        }

        //4.二次确认转入账户的姓氏：张三   ====>   *三
        while (true) {
            String showName = "*" + toAccount.getUsername().substring(1);
            System.out.println("您当前要为"+showName+"转账！");
            System.out.println("请输入姓氏确认：");
            String okName = sc.next();

            if(!toAccount.getUsername().startsWith(okName)){
                System.out.println("输入的姓氏有误！");
                continue;
            }
            break;
        }


        //5.进行转账操作，接收转账的金额
        double money = 0;
        while (true) {
            System.out.println("请输入转账金额：");
            money = sc.nextDouble();

            //5.1 判断余额是否充足
            if(money  > loginAccount.getMoney()){
                System.out.println("余额不足！转帐失败！");
                continue;
            }
            break;
        }

        //5.2 转账：
        // 转出账户-钱
        loginAccount.setMoney(       loginAccount.getMoney()    -     money         );
        // 转入账户+钱
        toAccount.setMoney(           toAccount.getMoney()      +        money      );

        //6.提示结果
        System.out.println("恭喜，"+loginAccount.getUsername()+"转帐成功！余额："+loginAccount.getMoney());
    }

    // 修改密码
    public void updatePassword(){

    }

    // 注销账户
    public boolean destroyAccount(){
        //1.二次销户操作确认
        System.out.println("您真的销户吗？y/n");
        String choose = sc.next();
        if(!"y".equals(choose)){
            System.out.println("取消销户！");
            return false;
        }

        //2.判断账户余额是否为0
        if(loginAccount.getMoney() != 0){
            System.out.println("账户余额有未取款金额，请先取款！");
            return false;
        }

        //3.销户操作：从账户集合中，删除此账户
        accounts.remove(loginAccount);
        return true;
    }


}



















